package com.liusand.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.liusand.common.UserThreadLocalUtils;
import com.liusand.dto.OrderDto;
import com.liusand.dto.UpdateOrderDto;
import com.liusand.exception.OrderException;
import com.liusand.mapper.AddressBookMapper;
import com.liusand.mapper.OrderMapper;
import com.liusand.mapper.ShoppingCartMapper;
import com.liusand.pojo.Order;
import com.liusand.pojo.OrderDetail;
import com.liusand.pojo.PageInfo;
import com.liusand.pojo.ShoppingCart;
import com.liusand.service.OrderService;
import com.liusand.vo.AddressBookVo;
import com.liusand.vo.ClientOrderDetailVo;
import com.liusand.vo.ClientOrderVo;
import com.liusand.vo.OrderVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static cn.hutool.core.bean.BeanUtil.copyToList;

/**
 * @author :liusha
 * packageName :com.liusand.service.impl
 * fileName :OrderServiceImpl
 * creationTime :2022/12/5 18:50
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private ShoppingCartMapper shoppingCartMapper;

    @Override
    public PageInfo<OrderVo> page(LocalDateTime beginTime, LocalDateTime endTime, String number, Integer page, Integer pageSize) {
        int start = (page - 1) * 10;
        List<OrderVo> orderVoList = orderMapper.page(beginTime, endTime, number, start, pageSize);
        PageInfo<OrderVo> pageInfo = new PageInfo<>();
        pageInfo.setRecords(orderVoList);
        pageInfo.setCurrent(page);
        pageInfo.setSize(pageSize);
        Long total = orderMapper.countPage(beginTime, endTime, number);
        pageInfo.setTotal(total);
        return pageInfo;
    }

    @Override
    public boolean modifyOrderStatus(UpdateOrderDto updateOrderDto) {
        if(updateOrderDto == null){
            return false;
        }
        int updateResult = orderMapper.updateOrderStatus(updateOrderDto);
        return updateResult == 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submit(OrderDto orderDto) {
        if(orderDto == null){
            return false;
        }
        Order order = new Order();
        String userId = UserThreadLocalUtils.getId();
        BeanUtils.copyProperties(orderDto, order);
        String id = IdUtil.getSnowflakeNextIdStr();
        order.setId(id);
        order.setNumber(order.getId());
        order.setStatus(2);
        order.setUserId(userId);
        order.setOrderTime(LocalDateTime.now());
        order.setCheckoutTime(LocalDateTime.now());

        //计算总金额
        BigDecimal total = new BigDecimal(0);
        List<ShoppingCart> shoppingCart = shoppingCartMapper.selectShoppingCartByUserId(userId);
        for(ShoppingCart sc : shoppingCart){
            total = total.add(sc.getAmount().multiply(new BigDecimal(sc.getNumber())));
        }
        order.setAmount(total);
        List<OrderDetail> orderDetailList = BeanUtil.copyToList(shoppingCart, OrderDetail.class);
        for(OrderDetail orderDetail : orderDetailList){
            orderDetail.setId(IdUtil.getSnowflakeNextIdStr());
            orderDetail.setOrderId(id);
        }
        int insertOrderResult = orderMapper.insertOrder(order);
        if(insertOrderResult != 1){
            throw new OrderException("添加订单失败");
        }
        int insertOrderDetailsResult = orderMapper.insertOrderDetails(orderDetailList);
        if(insertOrderDetailsResult != orderDetailList.size()){
            throw new OrderException("添加订单失败");
        }
        shoppingCartMapper.deleteAllShoppingCartByUserId(userId);
        return true;
    }

    @Override
    public PageInfo<ClientOrderVo> userPage(Integer page, Integer pageSize) {
        Integer start = (page - 1) * 10;
        String userId = UserThreadLocalUtils.getId();
        List<ClientOrderVo> clientOrderVoList = orderMapper.userPage(userId, start, pageSize);
        if(clientOrderVoList != null && clientOrderVoList.size() != 0){
            Set<String> ids = clientOrderVoList.stream().map(ClientOrderVo::getId).collect(Collectors.toSet());
            List<OrderDetail> orderDetailList = orderMapper.selectOrderDetailsByOrderIds(ids);
            Map<String, List<OrderDetail>> map = orderDetailList.stream().collect(Collectors.groupingBy(OrderDetail::getOrderId));
            for(ClientOrderVo clientOrderVo : clientOrderVoList){
                List<OrderDetail> list = map.get(clientOrderVo.getId());
                List<ClientOrderDetailVo> clientOrderDetailVos = copyToList(list, ClientOrderDetailVo.class);
                clientOrderVo.setOrderDetails(clientOrderDetailVos);
            }
        }
        PageInfo<ClientOrderVo> pageInfo = new PageInfo<>();
        pageInfo.setRecords(clientOrderVoList);
        pageInfo.setCurrent(page);
        pageInfo.setSize(pageSize);
        Long total = orderMapper.countUserPage(userId);
        pageInfo.setTotal(total);
        pageInfo.setPages(10);
        return pageInfo;
    }
}
